 const ImgDraw=(function(){
    /***
     * this.ctx是虚拟canvas上的画笔
     */
    var depl={};    //配置文件
    
    var depl_back={  //备份的配置文件    
        pin:{
            color:{
                
                t:"#CC6666",
                ts_t:"#990066",
                ts_b:"#990066",
                tp_t:"#CCCCFF",
                tp_b:"#CCCCFF",
                
                i:"#99CCCC",
                is_t:"#990066",
                is_b:"#990066",
                ip_t:"#CCCCFF",
                ip_b:"#CCCCFF",
                
                b:"#336699",
                bs_t:"#990066",
                bs_b:"#990066",
                bp_t:"#CCCCFF",
                bp_b:"#CCCCFF",
                
                drill:"#CCCCCC",//过孔颜色
                contour:"#99CCCC",   //pin描边颜色 
            }
        },

        layer:{
            st:{
                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },
                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },  

            },

            sb:{
                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },  

            },

            at:{
                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            ab:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            sm_t:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            sm_b:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            et:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            eb:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },   

            },

            bt:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            bb:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            },

            pt:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },  

            },

            pb:{

                text:{
                    color_text:"black",//文字颜色
                    color_border:"red",//文字范围
                    typeface:"微软雅黑",//字体
                    text_size:"10",//字号
                },

                path:{
                    color_line:"#1a2273",//线颜色
                    line_width:1,//线宽
                },

                shape:{
                    color_fill:"green",//铜皮填充颜色
                    color_out:"#83b31e",//铜皮镂空部分颜色 
                    color_line:"while",//描边颜色
                    line_width:1,//线宽
                },    

            }

        },

        color_origin:"#a4bfa4",     //原点颜色

        typeface:"微软雅黑",            //全局字体 

        text_size:"20px",           //全局字号

        line_width:1,               //线宽

        txt_color:"black",

        

        highlight_color:"#ffbc00bd",  //强调的颜色

        highlight_scope:10,           //强调的范围

        grid_color:"#c0c0c0",       //格点颜色

    };

    var arr_dete={//数组映射
        pin:["fill","color","direction","color_line"],
        shape:["fill","color","color_line","stroke"],
        txt:["typeface","text_size","text_color"],
        path:["stroke"],
    };
    
    var gridLengthw=0,
        gridLengthh=0;
    var tidy={//整理图形对象的配置属性
        pin:function(pin){//检测pin中的配置相关信息
            let arr=arr_dete.pin;
            arr.forEach(value=>{
                if(!pin[value]){
                    pin[value]=true;
                }
            });
            return pin;
        },
        txt:function(){

        },
        shape:function(){

        },
        path:function(){

        },
        isEmpty:function(obj){
            try {
                let lock=false;
                if(!obj){
                    return true;
                }
                if(JSON.stringify(obj) === "{}"){
                    lock=true;
                }
                if(Object.getOwnPropertyNames(obj).length==0){
                    lock=true;
                }
                return lock;
            } catch (error) {
                return false;
            }
            
        },
        xbox:function(path){//获取路径的最大最小值
            let xbox={
                w:0,
                h:0
            };
            let x_all=[],
                y_all=[];
            path.forEach(line=>{
                let name=line.name.toUpperCase();
                if(name=="LINE"){
                    x_all.push(line.st_x);
                    x_all.push(line.sp_x);
                    y_all.push(line.st_y);
                    y_all.push(line.sp_y);
                }
            });
            let max_x = Math.max.apply(null,x_all),
                max_y = Math.max.apply(null,y_all),
                min_x = Math.min.apply(null,x_all),
                min_y = Math.min.apply(null,y_all);
                xbox.w = Math.sqrt(Math.pow(min_x-max_x,2)+Math.pow(max_y-max_y,2)),
                xbox.h = Math.sqrt(Math.pow(min_x-min_x,2)+Math.pow(max_y-min_y,2));

            return xbox;
        },

        //引脚上计算字体大小
        text_size:function(type,r,w,h){
            var size=depl.text_size;
            var area=0;
            switch(type){
                case 'C':case 'CIRCLE':
                case 'H_C':case 'CIRCLE_DRILL':
                    var area=3.14*r*r*1;
                    break;
                case 'S':case 'SQUARE':case "CS":
                case 'H_S':case 'SQUARE_DRILL':
                    var area=w*h*1;
                    break;
                case 'OC':
                case 'H_OC':
                    var area=3.14*r*r;
                    break;
                case 'OV':case 'OBLONG_Y':
                case 'H_OV':case 'OBLONG_X':
                    if(w<h){
                        area=w*w;
                    }else{
                        area=h*h;
                    }
                    
                    break;
                case 'POLY':
                case 'H_POLY':
                    area=3.14*r*r;
                    break;
                case 'PATH':
                case 'H_PATH'://画笔，pin路径，坐标x，坐标y，旋转角度（pin整体+pin单层），偏移x，偏移y，颜色
                    if(w<h){
                        h=w; 
                    }else{
                        w=h;
                    }
                    area=w*h*1;
                    break;
                case 'nil':
                    break;
                /*default:
                    window.alert("pin图形绘制遗失"+h_form);
                    break;*/
                    
            }
            size = Math.sqrt(area) * 0.2;
            if(size <= 4){
                size = 0;
            }
            return size;
        },
        //根据字符数量计算字体大小
        textSize:function(txt){
            return 
        },
        judge_arc:function(obj,x,y){
            //先判断点在不在圆上
            let status=false,
                r=arc.r,
                st_x=arc.st_x,
                st_y=arc.st_y,
                sp_x=arc.sp_x,
                sp_y=arc.sp_y,
                line_w=arc.width/2,
                o_x=arc.o_x,
                o_y=arc.o_y,
                dir=arc.arc_r,
                rot = arc.rotate;
            let gap=Math.sqrt((Math.pow(x-o_x,2)+Math.pow(y-o_y,2)));
            if(r-line_w<gap&&gap<r+line_w){//满足圆的方程
                let median=sountAngle(x-o_x ,  y-o_y),
                    st = sountAngle(st_x-o_x, st_y-o_y),
                    sp = sountAngle(sp_x-o_x, sp_y-o_y);
                //计算夹角
                let angle_ref=[],
                    angle_acc=[],
                    angle_st=180*st.angle/Math.PI,
                    angle_me=180*median.angle/Math.PI,
                    angle_sp=180*sp.angle/Math.PI;
                angle_ref=[angle_st,angle_sp];
                let maxAngle=Math.max.apply(null,angle_ref),
                    minAngle=Math.min.apply(null,angle_ref);
                if(st_x==sp_x&&st_y==sp_y){
                    status=true;
                }else{
                    //判断夹角是否过0点
                    let angle_lock=false,
                        qua_st=st.qua,
                        qua_sp=sp.qua;
                    if(!dir){//顺时针
                        if(qua_st==1&&qua_sp==2||qua_st==1&&qua_sp==3
                            ||qua_st==1&&qua_sp==4||qua_st==2&&qua_sp==3
                            ||qua_st==2&&qua_sp==4||qua_st==3&&qua_sp==4
                            ){
                            angle_lock=true;
                        }else if(qua_st==1&&qua_sp==1
                            ||qua_st==4&&qua_sp==4){
                            if(st_y<sp_y){
                                angle_lock=true;
                            }
                        }else if(qua_st==2&&qua_sp==2
                            ||qua_st==3&&qua_sp==3){
                            if(st_y>sp_y){
                                angle_lock=true;
                            }
                        }
                    }else{//逆时针
                        if(qua_st==2&&qua_sp==1||qua_st==3&&qua_sp==1
                        ||qua_st==3&&qua_sp==2||qua_st==4&&qua_sp==1
                        ||qua_st==4&&qua_sp==2||qua_st==4&&qua_sp==3){
                            angle_lock=true;
                        }else if(qua_st==1&&qua_sp==1
                            ||qua_st==4&&qua_sp==4){
                            if(st_y>sp_y){
                                angle_lock=true;
                            }
                        }else if(qua_st==2&&qua_sp==2
                            ||qua_st==3&&qua_sp==3){
                            if(st_y<sp_y){
                                angle_lock=true;
                            }
                        }
                    }
                    if(angle_lock){
                        if(minAngle<angle_me&&angle_me<maxAngle){
                            status=true;
                        }
                    }else{
                        
                        if(minAngle>=angle_me||angle_me>maxAngle){
                            status=true;
                        }
                    }
                }
            }
            return status;
            
            function sountAngle(x,y){
                var angle=0,
                    qua=0;
                if(x>0&&y>=0){
                    angle=Math.atan(y/x);
                    qua=1;
                }else if(x<=0&&y>0){
                    x=Math.abs(x);
                    angle=Math.atan(x/y)+0.5*Math.PI;
                    qua=2;
                }else if(x<0&&y<=0){
                    x=Math.abs(x);
                    y=Math.abs(y);
                    angle=Math.atan(y/x)+Math.PI;
                    qua=3;
                }else if(x>=0&&y<0){
                    y=Math.abs(y);
                    angle=Math.atan(x/y)+1.5*Math.PI;
                    qua=4;
                }
                return {
                    angle:angle,
                    qua:qua,
                };
            
            }
        }
        
    };
    //工具方法
    var tool={
        init:function(obj){//初始化
            if(!obj){
                return;
            }
            if(obj.deploy){//设置基本配置
                this.setDeploy(obj.deploy);
            }
            if(obj.origin){//设置原点
                this.setOrigin(obj.origin);
            }
            if(obj.prop){//设置格点
                this.setGrid(obj.prop);
            }
            
        },
        createCtx:function(){//创建画笔
            this.actual_canvas.width=this.actual_canvas.width;
            return this.actual_canvas.getContext("2d");
        },
        createVirCtx:function(width,height){//创建虚拟画布画笔
            this.virtual_canvas=document.createElement('canvas'); // 创建一个新的canvas
            this.virtual_canvas.width=  width;
            this.virtual_canvas.height= height;
            var ctx=this.virtual_canvas.getContext("2d");
            return ctx;
        },
        setCanvasSize:function(obj){
            this.virtual_canvas.width = obj.width;
            this.virtual_canvas.height= obj.height;
            // this.actual_canvas.width  = obj.width;  
            // this.actual_canvas.height = obj.height;
            this.setOrigin(this.origin);
        },
        setOrigin:function(org){//设置原点
            if(!org){
                return;
            }
            this.origin=org;
            this.ctx.translate(this.origin.x,this.origin.y);
        },
        setCanvasRotate:function(rot){
            this.canvasRoatate= rot;
        },
        setDeploy:function(data){//设置配置
            if(!data){
                depl=depl_back;//备用配置
                return;
            }
            depl=data;
        },
        setGrid:function(grid){//设置格点
            if(!grid){
                return;
            }
            //rotWH = this.getCanvasRotWh();
            
            let gapx=grid.x,
                gapy=grid.y;
            this.gridObj=grid;
            this.clear();
            this.ctx.save();

            /*this.ctx.translate(this.origin.x,this.origin.y)
            this.ctx.rotate(this.canvasRoatate*Math.PI/180)
            this.ctx.translate(-this.origin.x,-this.origin.y)*/
            this.ctx.globalAlpha=0.5;
            this.ctx.strokeStyle = "black";
            this.ctx.lineWidth = 0.5;
            let w=this.ctx.canvas.width,
                h=this.ctx.canvas.height;
            let o_x=this.origin.x,
                o_y=this.origin.y;
            //原点在界面右边时
            if(o_x<w/2){
                if(o_x<0){
                    o_x=w-o_x;
                }else{
                    o_x=w+o_x;
                }
            }
            //原点在上部分时
            if(o_y<h/2){
                if(o_y<0){
                    o_y=h-o_y;
                }else{
                    o_y=h+o_y;
                }
            }

            let gap_numx=o_x*2/gapx,//格点数
                gap_numy=o_y*2/gapy;
            let lengthx=gap_numx*gapx/2,//格点线长度
                lengthy=gap_numy*gapy/2;

                gridLengthw=lengthx;
                gridLengthh=lengthy;
                
            for(let a=0,x=0;a<gap_numx/2;a+=1,x+=gapx){//右竖线
                this.ctx.beginPath();
                this.ctx.moveTo(x, -lengthy);
                this.ctx.lineTo(x,  lengthy);
                this.ctx.stroke();
            }   
            for(let a=0,x=0;a<gap_numx/2;a+=1,x-=gapx){//左竖线
                this.ctx.beginPath();
                this.ctx.moveTo(x, -lengthy);
                this.ctx.lineTo(x,  lengthy);
                this.ctx.stroke();
            } 
            for(let a=0,y=0;a<gap_numy/2;a+=1,y+=gapy){//下横线
                this.ctx.beginPath();
                this.ctx.moveTo(-lengthx, y);
                this.ctx.lineTo( lengthx, y);
                this.ctx.stroke();
            }
            for(let a=0,y=0;a<gap_numy/2;a+=1,y-=gapy){//上横线
                this.ctx.beginPath();
                this.ctx.moveTo(-lengthx, y);
                this.ctx.lineTo( lengthx, y);
                this.ctx.stroke();
            }
            this.ctx.restore();
            
            //绘制原点标示
            this.drawOrgSeat();

            this.drawCanvas();
            

            
        },
        //绘制原点标示
        drawOrgSeat(){
            let color="#1e1e1e",
                line_w=this.gridObj.x/20;

            this.circle({
                x:0,
                y:0,
                r:this.gridObj.x/2,
                stroke:true,
                fill:false,
                color_line:color,
                line_w:line_w,
                
            });
            this.line({
                st_x:0,
                st_y:-gridLengthh,
                sp_x:0,
                sp_y:gridLengthh,
                color:color,
                line_w:line_w,
            });
            this.line({
                st_x:-gridLengthw,
                st_y:0,
                sp_x:gridLengthw,
                sp_y:0,
                color:color,
                line_w:line_w,
            });
        },
        clear:function(){
            this.virtual_canvas.width=this.actual_canvas.width;
            this.actual_canvas.width= this.actual_canvas.width;
            this.setOrigin(this.origin);
        },
        redrawAll:function(obj){//绘制整体图形
            if(!obj){
                return;
            }
            if(tidy.isEmpty(depl)){
                depl=depl_back;
            }
            //rotWH = this.getCanvasRotWh();

            this.drawCanvas_ver(obj);
        },
        drawCanvas_ver:function(obj){
            if(obj.pins&&obj.pins.length>0){
                this.ctx.save();
                this.drawPins(obj.pins);
                this.ctx.restore();
            }
            if(obj.paths&&obj.paths.length>0){
                this.ctx.save();
                this.drawPaths(obj.paths);
                this.ctx.restore();
            }
            if(obj.shapes&&obj.shapes.length>0){
                this.ctx.save();
                this.ctx.globalAlpha=0.5;
                this.drawShapes(obj.shapes);
                this.ctx.restore();
            }
            if(obj.texts&&obj.texts.length>0){
                this.ctx.save();
                this.drawTexts(obj.texts);
                this.ctx.restore();
            }
            
            this.drawCanvas();
        },
        //绘制pin
        drawPins:function(pins){ 
            if(!pins||pins.length==0){
                return;
            }
            var txtlist={};
            pins.forEach(pin=>{
                if(pin){
                    let obj={
                        form:pin.data.form,
                        fill:true,
                        stroke:false,
                        rotate:pin.data.rotate/1+pin.data.pRotate/1,
                        x:pin.data.x,
                        y:pin.data.y,
                        r:pin.data.r,
                        w:pin.data.w,
                        h:pin.data.h,
                        alpha:pin.alpha,
                        arc_r:pin.data.arc||true,
                        skewing_x:pin.data.skewing_x,
                        skewing_y:pin.data.skewing_y,
                        color:pin.fillStyle,
                        color_line:pin.strokeStyle,
                    };
                    if(pin.pin_layer == "drill"){

                        console.log(pin.data.rotate,pin.data.pRotate)
                        console.log(pin.data.rotate/1+pin.data.pRotate/1)
                    }
                    
                    /*if(obj.form=="C"){
                        obj.r=obj.w;
                    }*/
                    
                    if(!tidy.isEmpty(obj)&&obj.form){
                        switch(obj.form.toUpperCase()){
                            case "C":
                                this.circle(obj);
                                break;
                            case "S":
                                this.rectangle(obj);
                                break;
                            case "CS":
                                this.rectangle_c(obj);
                                break;
                            case "OV":
                                this.long_circle(obj);
                                break;
                            case "OC":
                                this.octagon(obj);
                                break;
                            case "POLY":
                                obj.num=pin.data.num;
                                this.polygon(obj);
                                break;
                            case "PATH":
                                
                                obj.path=pin.data.path;
                                let xbox=tidy.xbox(obj.path);
                                obj.w =xbox.w;
                                obj.h =xbox.h;
                                this.path_p(obj);
                                break;
                            default:
                                console.log("外径图形描述有异常:"+obj.form);
                                break;
                        }
                         
                    }
                    else{
                        //console.log(pin);
                    }

                    var size=tidy.text_size(obj.form,obj.r,obj.w,obj.h);
                    var txt={};
                    /*if(pin.pin_layer=="drill"){
                        if(){

                        }
                    }else{
                        
                    }*/
                    txt={
                        text_size:size,
                        color:"black",
                        content:pin.pin_num,
                        x:obj.x+obj.skewing_x/1,
                        y:obj.y+obj.skewing_y/1,
                        typeface:"微软雅黑",
                    }
                    if(!size){
                        return;
                    }
                    txtlist[pin.id]=txt;
                }
                
            });
            //绘字
            let pinIds = Object.keys(txtlist);
            if(pinIds.length>0){
                pinIds.forEach(id=>{
                    this.text(txtlist[id]);
                });
            }
        },
        //绘制丝印线
        drawPaths:function(paths){
            if(!paths||paths.length==0){
                return;
            }
            
            paths.forEach(path=>{
                if(!tidy.isEmpty(path)){//不是空对象
                    let line=path.data,
                    st_x=line.st_x/1,
                    st_y=line.st_y/1,
                    sp_x=line.sp_x/1,
                    sp_y=line.sp_y/1,
                    line_w=line.width/1;

                    line.line_w=line_w;
                    line.color = path.strokeStyle;
                    line.color_line = path.strokeStyle;
                    line.stroke=true;
                    line.fill=false;
                   
                   // let form=(path.data.name?path.data.name:"nil").toUpperCase();
                    let form=(path.form?path.form:"nil").toUpperCase();
                    if(form=="LINE"){
                        this.line(line);
                    }else if(form=="ARC"){
                        let begin=0,
                            end  =0,
                            mode=true;
                        if(st_x==sp_x&&st_y==sp_y){
                            begin=10;
                        }else{
                            mode=line.arc_r;
                            begin=this.radian_verdict(st_x-line.o_x/1,st_y-line.o_y/1),
                            end  =this.radian_verdict(sp_x-line.o_x/1,sp_y-line.o_y/1);
                        }
                        //console.log(st_x,st_y);
                        line.x=line.o_x/1;
                        line.y=line.o_y/1;
                        line.st=begin;
                        line.sp=end;
                        line.mode=mode;
                        this.arc_l(line);
                    }else if(form=="C"){
                        this.circle(line);
                    }else if(form=="S"){
                        this.rectangle(line);
                    }else if(form=="OV"){
                        this.long_circle(line);
                    }else if(form=="OC"){
                        this.octagon(line);
                    }else if(form=="POLY"){
                        this.polygon(line);
                    }else if(form=="LS"){
                        this.rectangle_c(line);
                    }else if(form=="nil"){
                        console.error("路径有异常"+form);
                    }
                }
            });
        },
        //绘制铜皮
        drawShapes:function(shapes){
            if(!shapes||shapes.length==0){
                return;
            }
            let fillStyle = "red";
            var begin_fun=(obj,type)=>{
                if(obj instanceof Array){
                    let temp = {
                        fill:true,
                        stroke:false,
                        color:fillStyle,
                        path:obj,
                    }
                    if(type){
                        temp.color="black";
                    }
                    this.shape_path_l(temp);
                }else{
                    let form=(obj.name?obj.name:"nil").toUpperCase();
                    obj.fill = true;
                    obj.stroke =false;
                    if(form =="C"){
                        this.shape_circle(obj)
                    }else if(form=="S"){
                        this.shape_rectangle(obj);
                    }else if(form=="OV"){
                        this.shape_long_circle(obj);
                    }else if(form=="OC"){
                        this.shape_octagon(obj);
                    }else if(form=="POLY"){
                        this.shape_polygon(obj);
                    }else if(form=="LS"){
                        this.shape_rectangle_c(obj);
                    }else if(form=="nil"){
                        console.error("路径有异常"+obj.name);
                    }
                }
            }
            
            shapes.forEach(shape=>{
                this.ctx.save();
                fillStyle = shape.fillStyle;
                this.setAlpha(shape.alpha);//透明度
                this.setCtxMode(1);
                this.ctx.restore();
                begin_fun(shape.data.outline);
                this.setCtxMode(7);
                this.setAlpha(1);//透明度
                shape.data.fill.forEach(aa=>{
                    begin_fun(aa,true);
                });
            });

            this.drawCanvas();
            
        },
        //绘制文字
        drawTexts:function(texts){
            if(!texts||texts.length==0){
                return;
            }
            texts.forEach(txt=>{
                if(txt.data&&!tidy.isEmpty(txt.data)){
                    let obj={
                        x:txt.data.x,
                        y:txt.data.y,
                        w:txt.data.textwidth ,
                        h:txt.data.textheight,
                        rot:txt.data.rotate||0,
                        skewing_x:txt.data.skewing_x,
                        skewing_y:txt.data.skewing_y,
                        fontWeight:txt.data.fontWeight,
                        text_size:txt.data.textblock||"5",
                        color:txt.fillStyle||"black",
                        typeface:txt.typeface||"微软雅黑",
                        strokeRect:txt.strokeRect,
                        content:txt.data.content,
                    };
                    var new_txt=this.text(obj);
                    txt.data.textwidth=new_txt.width;
                    txt.data.textheight=new_txt.height;
                }    
            });
        },
        //绘制检查线
        drawExamine:function(arr){
            if(arr.length<=0||!arr.length){
                return;
            }
            arr.forEach(row=>{
                if(row.length>1){
                    for(let i=0;i<row.length;i++){
                        let st=row[i];
                        let sp=i<row.length-1?row[i+1]:row[i];
                        

                        let r=Math.sqrt(Math.pow(st[0]-sp[0],2)+Math.pow(st[1]-sp[1],2))/2;
                        let midpointX=(st[0]+sp[0])/2,//中点
                            midpointY=(st[1]+sp[1])/2;
                        let con_x,con_y;
                        let k1;

                        if(st[0]==sp[0]){//x轴相等
                            if(st[1]>sp[1]){
                                con_x=midpointX-r/2;
                                con_y=midpointY;
                            }else{
                                con_x=midpointX+r/2;
								con_y=midpointY;
                            }
                            
                        }else if(st[1]==sp[1]){//y轴相等
                            if(st[0]<sp[0]){
								con_x=midpointX;
                                con_y=midpointY-r/2;
                            }else{
								con_x=midpointX;
                                con_y=midpointY+r/2;
                            }
                            
                        }else{
                            let x1=st[0],y1=st[1],
                                x2=midpointX,y2=midpointY;
                            k1=(y2-y1)/(x2-x1);
                            let k2=-1/k1;
                            if(st[0]<sp[0]&&st[1]<sp[1]){//左上-右下
                                con_x=midpointX+Math.sqrt((r*r/(k2*k2+1)))/2;
                                con_y=(con_x-midpointX)*k2+midpointY;
                                //con_y=midpointY-k2*(midpointX-con_x);
                            }else if(st[0]<sp[0]&&st[1]>sp[1]){//左下-右上
                                con_x=midpointX-Math.sqrt((r*r/(k2*k2+1)))/2;
                                con_y=((con_x-midpointX)*k2)+midpointY;
                                //con_y=midpointY+k2*(midpointX-con_x);
                            }else if(st[0]>sp[0]&&st[1]>sp[1]){//右下-左上
                                con_x=midpointX-Math.sqrt((r*r/(k2*k2+1)))/2;
                                con_y=midpointY-k2*(midpointX-con_x);
                            }else if(st[0]>sp[0]&&st[1]<sp[1]){//右上-左下
                                con_x=midpointX+Math.sqrt((r*r/(k2*k2+1)))/2;
                                con_y=midpointY-k2*(midpointX-con_x);
                            }
                            
                         }

                        let obj={
                            st_x:st[0],
                            st_y:st[1],
                            sp_x:sp[0],
                            sp_y:sp[1],
                            gap:r/2,
                            rotate:(Math.atan(k1) * 180 / Math.PI.toFixed(0))/1,
                            con_x:con_x,
                            con_y:con_y,
                        };

                        if(i<=row.length-2){
                            this.arrowhead(obj);
                        }
                    };
                }
            });
            this.drawCanvas();
        },
        setCtxMode:function(mode){//虚拟画笔的叠加模式
            var type="";
            switch(mode){
                case 1:
                    type="source-over";
                    break;
                case 2:
                    type="destination-in";
                    break;
                case 3:
                    type="source-in";
                    break;
                case 4:
                    type="source-out";
                    break;
                case 5:
                    type="lighter";
                    break;
                case 6:
                    type="xor";
                    break;
            }
            this.ctx.globalCompositeOperation=type;
            
        },
        setAccCtxMode:function(mode){//实际画笔的叠加模式
            var type="";
            switch(mode){
                case 1:
                    type="source-over";
                    break;
                case 2:
                    type="destination-in";
                    break                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    ;
                case 3:
                    type="source-in";
                    break;
                case 4:
                    type="source-out";
                    break;
                case 5:
                    type="lighter";
                    break;
                case 6:
                    type="xor";
                    break;
            }
            this.actual_ctx.globalCompositeOperation=type;
            
        },
        setMeasure:function(obj){//标注测量距离
            let box = {
                box1:{
                    x:0,
                    y:0,
                    lock:true,
                    row1:{},
                    row2:{},
                },
                box2:{
                    x:0,
                    y:0,
                    lock:true,
                    row1:{},
                    row2:{},
                },
                gap:{
                    txt:{},
                    x1:0, 
                    y1:0, 
                    x2:0, 
                    y2:0, 
                    o_x:0,
                    o_y:0,
                },
            };
            let units=obj.units,
                obj_st=obj.start,
                obj_sp=obj.end,
                gap = "中心间距："+(obj.dist||0)+units,
                gap_w="水平间距："+(obj.w||0)+units,
                gap_h="垂直间距："+(obj.h||0)+units;
            let grid=0,
                box1={};
            if(obj_st&&!tidy.isEmpty(obj_st)){
                grid++;
                let type = obj_st.type.toUpperCase();
                let x=obj_st.x,
                    y=obj_st.y,
                    w=(obj_st.w||0)+units,
                    h=(obj_st.h||0)+units,
                    m_w=obj_st.scaleW||0,
                    m_h=obj_st.scaleH||0;
                if(m_h<m_w){
                    m_w=m_h;
                }
                if(m_w==0||m_h==0){
                    m_w=12;
                }
                let lock=false,
                    row1={},
                    row2={};
                switch(type){
                    case "PINS":
                        let size=m_w/w.toString().length;
                        row1={
                            x:x/1,//+m_w/2,
                            y:y/1+m_w/2,
                            content:"宽度:"+w+"高度:"+h, 
                            text_size:size,
                            color:"green",
                        };
                        if(obj_st.drill&&obj_st.drill.length>0){
                            let con="";
                            obj_st.drill.forEach(function(hol,i){
                                let h_w=hol.w+units,
                                    h_h=hol.h+units;
                                con+="过孔"+(i+1)+":宽度："+h_w+" 高度："+h_h;
                                if(i<obj_st.drill.length-2){
                                    con+=",";
                                }
                            });
                            //如果有过孔则重新计算字体大小
                            //size=m_w/con.length;
                            //row1.text_size=size*2;
                            row2={
                                x:row1.x,//+pad.size,
                                y:row1.y/1+row1.text_size/1,
                                content:con, 
                                text_size:size/2,
                                color:"green",
                            };
                        }
                        lock=true;
                        break;
                }
                box1={
                    x:x,
                    y:y,
                    k:m_w,
                    lock:lock,
                    row1:row1,
                    row2:row2,
                };

            }
            let box2={};
            if(obj_sp&&!tidy.isEmpty(obj_sp)){
                grid++;
                let type = obj_sp.type.toUpperCase();
                let x=obj_sp.x,
                    y=obj_sp.y,
                    w=(obj_sp.w||0)+units,
                    h=(obj_sp.h||0)+units,
                    m_w=obj_sp.scaleW||0,
                    m_h=obj_sp.scaleH||0;
                if(m_h<m_w){
                    m_w=m_h;
                }
                if(m_w==0||m_h==0){
                    m_w=12;
                }
                let lock=false,
                    row1={},
                    row2={};
                switch(type){
                    case "PINS":
                        let size=m_w/w.toString().length;
                        row1={
                            x:x/1,
                            y:y/1+m_w/2,
                            content:"宽度:"+w+"高度:"+h, 
                            text_size:size,
                            color:"green",
                        };
                        if(obj_sp.drill&&obj_sp.drill.length>0){
                            let con="";
                            obj_sp.drill.forEach(function(hol,i){
                                let h_w=hol.w+units,
                                    h_h=hol.h+units;
                                con+="过孔"+(i+1)+":宽度："+h_w+" 高度："+h_h;
                                if(i<obj_sp.drill.length-2){
                                    con+=",";
                                }
                            });
                            //如果有过孔则重新计算字体大小
                            //size=m_w/con.length;
                            //row1.text_size=size*2;
                            row2={
                                x:row1.x,
                                y:row1.y/1+row1.text_size/1,
                                content:con, 
                                text_size:size/2,
                                color:"green",
                            };
                        }
                        lock=true;
                        break;
                }
                box2={
                    x:x,
                    y:y,
                    k:m_w,
                    lock:lock,
                    row1:row1,
                    row2:row2,
                };
            }
            let box3={};
            if(grid==2){
                //校正标注位置
                let x1=obj_st.x||0,
                    y1=obj_st.y||0,
                    x2=obj_sp.x||0,
                    y2=obj_sp.y||0,
                    size = (Math.sqrt(Math.pow((x1-x2),2)+Math.pow((y1-y2),2))/
                    (gap.toString().length==1?4:gap.toString().length))/2;
                let new1_y,
                    new2_y;
                let minh1=obj_st.scaleW,
                    minh2=obj_sp.scaleW;
                if(obj_st.scaleH<obj_st.scaleW){
                    minh1=obj_st.scaleH;
                }  
                if(obj_sp.scaleH<obj_sp.scaleW){
                    minh2=obj_sp.scaleH;
                }  
                if(y1>y2){
                    new1_y=y1+minh1/2;
                    new2_y=y2-minh2/2;
                }else{
                    new1_y=y1-minh1/2;
                    new2_y=y2+minh2/2;
                }

                let min_w=0,

                    max_txt="0.00",
                    st_minw=0,
                    sp_minw=0,
                    st_w=0,
                    st_h=0,
                    sp_w=0,
                    sp_h=0;
                if(obj_st.type=="pins"){
                    st_w=obj_st.scaleW;
                    st_h=obj_st.scaleH;
                    st_minw=obj_st.scaleW;
                    if(obj_st.scaleW>obj_st.scaleH){
                        st_minw=obj_st.scaleH;
                    }
                }
                if(obj_sp.type=="pins"){
                    sp_w=obj_sp.scaleW;
                    sp_h=obj_sp.scaleH;
                    sp_minw=obj_sp.scaleW;
                    if(obj_sp.scaleW>obj_sp.scaleH){
                        sp_minw=obj_sp.scaleH;
                    }
                }
                //判断前后图形大小
                if(st_w*st_h>sp_w*sp_h){
                    if(!tidy.isEmpty(box1.row1)){
                        max_txt=box1.row1.content;
                    }
                    if(!tidy.isEmpty(box1.row2)){
                        max_txt=box1.row2.content;
                    }
                }else{
                    if(!tidy.isEmpty(box2.row1)){
                        max_txt=box2.row1.content;
                    }
                   
                    if(!tidy.isEmpty(box2.row2)){
                        max_txt=box2.row2.content;
                    }
                }
                min_w=st_minw;
                if(st_minw<sp_minw){
                    min_w=sp_minw;
                }
                //修改最大最小值
                min_w=min_w/(max_txt.length*0.25);
                if(box1&&!tidy.isEmpty(box1)){
                    if(box1.row1&&!tidy.isEmpty(box1.row1)){
                        box1.row1.y=new1_y;
                        box1.row1.text_size=min_w/1;
                    }
                    if(box1.row2&&!tidy.isEmpty(box1.row2)){
                        box1.row2.y=new1_y/1-box1.row1.text_size/1;
                        box1.row2.text_size=box1.row1.text_size*0.75;
                    }
                    
                }
                if(box2&&!tidy.isEmpty(box2)){
                    if(box2.row1&&!tidy.isEmpty(box2.row1)){
                        box2.row1.y=new2_y;
                        box2.row1.text_size=min_w;
                    }
                    if(box2.row2&&!tidy.isEmpty(box2.row2)){
                        box2.row2.y=new2_y/1+box2.row1.text_size/1;
                        box2.row2.text_size=box2.row1.text_size*0.75;
                    } 
                }
                
                //处理间隔信息
                box.lock=true;
                let content=gap,
                    o_x=(x1+x2)/2,
                    o_y=(y1+y2)/2,
                    x3=o_x,
                    y3=o_y,
                    x4=o_x,
                    y4=o_y;
                let num=content.length;
                /*if(x1==x2){//垂直
                    x3=x2;
                    y3=o_y/1-size/1;
                    x4=x3;
                    y4=o_y/1+size/1;

                }else if(y1==y2){//水平

                    x3=o_x/1-size*num/1;
                    y3=y1;
                    x4=o_x/1+size*num/1;
                    y4=y1;
                }else{

                }*/
                let sw_x=(size*gap.toString().length)/2-size/1;
                box3={
                    txt:{
                        x:(x1+x2)/2-sw_x,
                        y:(y1+y2)/2-size,
                        content:content, 
                        text_size:size,
                        textAlign:"left",
                        color:"green",
                    },
                    txtw:{
                        x:(x1+x2)/2-sw_x,
                        y:(y1+y2)/2,
                        content:gap_w, 
                        text_size:size,
                        color:"green",
                        textAlign:"left",
                    },
                    txth:{
                        x:(x1+x2)/2-sw_x,
                        y:(y1+y2)/2+size,
                        content:gap_h, 
                        text_size:size,
                        color:"green",
                        textAlign:"left",
                    },
                    x1:x1, 
                    y1:y1, 
                    x2:x2, 
                    y2:y2, 
                    o_x:o_x,
                    o_y:o_y,
                    x3:x3,
                    y3:y3,
                    x4:x4,
                    y4:y4,
                }
            }
            box.box1=box1;
            box.box2=box2;
            box.gap=box3;
            this.rectangleBox(box);
            this.drawCanvas();
        },
        setOpacity:function(number){
            number=number>1?1:number<0?0.1:number;
            this.actual_ctx.globalAlpha(number);
        },
        setAlpha:function(alpha){
            if(!alpha){
                alpha=1;
            }
            if(alpha<0){
                alpha=0.1;
            }
            if(alpha>0){
                alpha=1;
            }
            this.ctx.globalAlpha=alpha;
        },
        getPinNumber:function(obj){
            let mode=obj.mode;
            let xnum=obj.xnum;
            let ynum=obj.ynum;
            let txt = obj.txt;
            let ennum=textType(txt);
            let box=[];

            for(let i=0;i<xnum;i++){
                let row=[];
                for(let j=0;j<ynum;j++){
                    let br=false;
                    if(j === ynum-1){
                        br=true;
                    }
                    if(i==0&&j==0){
                        row.push(txt);
                    }else{
                        txt=textAdd(txt,ennum,br);
                        row.push(txt);
                    }
                    
                }
                box.push(row);
            }
            return box;

        },
        // 生成编号
        generateNumber(config){
            console.log(config)
            // let mode=obj.mode;
            let xnum = config.rowNumber;
            let ynum = config.colNumber;
            let txt  = config.startNum.toUpperCase();
            
            let ennum=this.textType(txt);
            let box=[];
            console.log(ennum)
            for(let i=0;i<xnum;i++){
                let row=[];
                let br=false;
                if(i>0){
                    br=true;
                }
                for(let j=0;j<ynum;j++){

                    if(i==0 && j==0){
                        row.push(txt);
                    }else{
                        txt=this.textAdd(txt,ennum,br);
                        row.push(txt);
                        ennum=this.textType(txt);
                    }

                    
                    br=false;
                }
                box.push(row);
            }
            return box;

        },
        textType(txt){
            let num=0;
            let test_en= new RegExp("^[A-Za-z]{"+num+"}\\d+$");
            for(let i=0;i<txt.length;i++){
                if(!test_en.test(txt)){
                    num++;
                    test_en=new RegExp("^[A-Za-z]{"+num+"}\\d+$");
                }
            }
            return num;
        },
        //自增
        textAdd(txt,ennum,br){//文本，字母个数，换行
            let text_en=/^[a-zA-Z]+$/,         //字母检测
                text_num=/^[0-9]*[1-9][0-9]*$/;//数字检测
            if(ennum==0){
                return txt/1+1;
            }else{//字母
                let en=txt.substr(0,ennum),
                    num=txt.substring(ennum);

                if(text_en.test(en)&&text_num.test(num)){//字母加数字
                    if(br){
                        txt=en_add(en)+(1);
                    }else{
                        txt=en+(num/1+1);
                    }
                    
                }else if(text_en.test(en)&&!text_num.test(num)){//纯字母
                    txt=en_add(en,br);
                    
                }
                return txt;
            }

            
            function en_add(entxt,br){//纯字母增
                let length=entxt.length-1;
                let en_end=entxt.substring(length);
                let en_new="";
                let en_head=entxt.substr(0,length);
                let enAddlock=true;
                let exclude =["I","O","Q","S","X","Z"]; //需要跳过的字母

                if(en_end.toUpperCase()=="Y"||br){
                    let endnum=-1;
                    if(br){
                        length=length-1;//摒弃最后一位
                    }
                    for(let i=length;i>=0;i--){
                        en_end=entxt.substr(i,length-i+1);
                        if(en_end.toUpperCase()!="Y"){
                            endnum=i;
                            break;
                        }
                    }
                    if(endnum==-1){
                        en_end="Y"
                        endnum=0;
                    }

                    if(br){
                        if(entxt.length==1){
                            en_end=entxt;
                            endnum=0;
                            console.log(en_end)
                        }else{
                            for(let k=endnum;k<length+1;k++){
                                en_new="A"+en_new;
                            }
                        }
                        
                    }else{
                        for(let k=endnum;k<length;k++){
                            en_new="A"+en_new;
                        }
                    }
                    
                    en_head=entxt.substr(0,endnum);
                    if(en_end.toUpperCase()=="Y"){
                        en_end="A";
                        if(en_head==""||en_head==null){
                            en_head="A";
                        }
                    }else{
                        en_end=String.fromCharCode(en_end.charCodeAt(0) + 1);
                        //检测是否是需要跳过的字母
                        exclude.forEach(value=>{
                            if(value==en_end){
                                en_end = String.fromCharCode(en_end.charCodeAt(0) + 1);
                            }
                        });
                    }
                    entxt=en_head+en_end+en_new;
                    
                }else{
                    en_end=String.fromCharCode(en_end.charCodeAt(0) + 1);
                    //检测是否是需要跳过的字母
                    exclude.forEach(value=>{
                        if(value==en_end){
                            en_end = String.fromCharCode(en_end.charCodeAt(0) + 1);
                        }
                    });
                    
                    entxt=en_head+en_end;
                }
                return entxt;
            }
        },
        //计算旋转后的长宽
        getCanvasRotWh(){
            let w=this.actual_ctx.canvas.width;
            let h=this.actual_ctx.canvas.height;
            let max_x = w/1,
                min_x = 0,
                min_y = 0,
                max_y = h/1;
            let printO = [w/2,h/2];
            let printA = [min_x,max_y];
            let printB = [max_x,max_y];
            let printC = [max_x,min_y];
            let printD = [min_x,min_y];

            printA = this.getSeat(printA,printO,this.canvasRoatate);
            printB = this.getSeat(printB,printO,this.canvasRoatate);
            printC = this.getSeat(printC,printO,this.canvasRoatate);
            printD = this.getSeat(printD,printO,this.canvasRoatate);
           
            max_x = printA[0]
            min_x = printA[0]
            min_y = printA[1]
            max_y = printA[1]
            
            let list=[printB,printC,printD];

            //重置最大最小值
            list.forEach(print=>{
                if(max_x<print[0]){
                    max_x=print[0];
                }
                if(min_x>print[0]){
                    min_x=print[0];
                }
                if(max_y<print[1]){
                    max_y=print[1];
                }
                if(min_y>print[1]){
                    min_y=print[1];
                }
                
            });
            w = Math.sqrt(Math.pow(max_x-min_x,2)+Math.pow(max_y-max_y,2));
            h = Math.sqrt(Math.pow(min_x-min_x,2)+Math.pow(max_y-min_y,2));
            this.ctx = this.createVirCtx(w,h);
            this.setOrigin();
            return {w:w,h:h};
        },
        //计算旋转后的点
	    getSeat(point,center,rotate){
	    	if(rotate==0){
                return point;
            }
            let angle = rotate * Math.PI / 180;
            let test= [(point[0] - center[0]) * Math.cos(angle) - (point[1] - center[1]) * Math.sin(angle) + center[0],
            		(point[0] - center[0]) * Math.sin(angle) + (point[1] - center[1]) * Math.cos(angle) + center[1]];
            
            return test;
	    },

        //增减字母的方法
        text_add:function(mode,content){
            let txt="",text_con="",
                
                text_en=/^[a-zA-Z]+$/,         //字母检测
                text_num=/^[0-9]*[1-9][0-9]*$/;//数字检测
            
            if(mode=="add"){//+
                //检测pinid实现自增
                if(content.length>1){
                    let na=content.substr(0,1),
                        me=content.substring(1);
                    if(content=="TEXT"){
                    
                    }else if(text_en.test(na)&&text_num.test(me)){
                        me=me/1+1;
                        text_con=na+me;
                    }else if(text_en.test(na)&&text_en.test(me)){
                        if(me=="Z"||me=="z"){
                            na=String.fromCharCode(na.charCodeAt(0) + 1);
                            if(me=="Z"){
                                me="A";
                            }else{
                                me="a";
                            }
                            
                        }else{
                            me=String.fromCharCode(me.charCodeAt(0) + 1);
                        }
                        text_con=na+me;
                    }else{
                        if(content=="TEXT"){
                    
                        }else if(text_en.test(content)){//字母自增
                            if(content=="z"||content=="Z"){
                                text_con=content;
                            }else{
                                text_con=String.fromCharCode(content.charCodeAt(0) + 1);
                            }
                            
                        }else if(text_num.test(content)){//数字自增
                            text_con=content/1+1;
                        }else{
                            text_con=content;
                        }
                    }
                    
                }else{
                    if(text_en.test(content)){//字母自增
                        if(content=="z"||content=="Z"){
                            text_con=content;
                        }else{
                            text_con=String.fromCharCode(content.charCodeAt(0) + 1);
                        }
                    }else if(text_num.test(content)){//数字自增
                        text_con=content/1+1;
                    }else{
                        text_con=content;
                    }
                }
                
            }else {//自减
                if(content.length>1){
                    let na=content.substr(0,1),
                        me=content.substring(1);
                    if(content=="TEXT"){
                    
                    }else if(text_en.test(na)&&text_num.test(me)){
                        me=me/1-1;
                        text_con=na+me;
                    }else if(text_en.test(na)&&text_en.test(me)){
                        if(me=="A"||me=="a"){
                            na=String.fromCharCode(na.charCodeAt(0) - 1);
                            if(me=="A"){
                                me="A";
                            }else{
                                me="a";
                            }
                            
                        }else{
                            me=String.fromCharCode(me.charCodeAt(0) - 1);
                        }
                        text_con=na+me;
                    }else{
                        if(content=="TEXT"){
                    
                        }else if(text_en.test(content)){//字母自减
                            if(content=="a"||content=="A"){
                                text_con=content;
                            }else{
                                text_con=String.fromCharCode(content.charCodeAt(0) - 1);
                            }
                        }else if(text_num.test(content)){//数字自减
                            text_con=content/1-1;
                        }else{
                            text_con=content;
                        }
                    }
                    
                }else{
                    if(text_en.test(content)){//字母自减
                        if(content=="a"||content=="A"){
                            text_con=content;
                        }else{
                            text_con=String.fromCharCode(content.charCodeAt(0) - 1);
                        }
                    }else if(text_num.test(content)){//数字自增
                        text_con=content/1-1;
                    }else{
                        text_con=content;
                    }
                }
            }
            return text_con;
        },
        drawCanvas:function(){//将虚拟canvas上的图绘到实际dom中
            let rot =this.canvasRoatate;
            if(!rot){
                rot = 0;
            }
            /*let newwh=this.getCanvasRotWh()
            var canvas4 = document.createElement("canvas");
            console.log(newwh)
            canvas4.width =  newwh.w;
            canvas4.height = newwh.h;
            var ctx4=canvas4.getContext("2d");
            ctx4.translate(canvas4.width/2,canvas4.height/2)
            ctx4.rotate(45*Math.PI/180)
            ctx4.translate(-canvas4.width/2,-canvas4.height/2)

            ctx4.drawImage(this.virtual_canvas,0,0,canvas4.width,canvas4.height);*/

            this.actual_ctx.drawImage(this.virtual_canvas,0,0,this.virtual_canvas.width,this.virtual_canvas.height);
            
        },
        //获取当前文本的长宽
        getTxtWidth(txtObj){
            let txt=txtObj.data.content,
                fontwidth=txtObj.data.fontWeight,//粗细
                textSize = txtObj.data.textblock,//字号
                typeface = txtObj.data.typeface;//字体

            this.ctx.textBaseline="middle";
            //" style variant weight 12px arial"
            this.ctx.font = "normal normal "+fontwidth+" "+textSize+"px "+typeface;
            this.ctx.textAlign = "center";  
            return this.ctx.measureText(txt);//文本对象
        }
    };

    var Shape_way={
        shape_circle: function (obj) {//圆形
            if (!obj) {
                return;
            }
            let x = obj.x || 0,
                r = obj.r || 0;
            let y = obj.y || 0;
            let skewing_x = obj.skewing_x || 0,
                skewing_y = obj.skewing_y || 0;
            let st = obj.st || 0,
                sp = obj.sp || 2;
            let dir = obj.arc_r || false,
                line_w = obj.line_w || 1;
            let fill = obj.fill || true,
                stroke = obj.stroke || false;
            let color = obj.color,
                color_line = obj.color_line;

            x = x + skewing_x;
            y = y + skewing_y;
            this.ctx.lineWidth = line_w;
            this.ctx.beginPath();
            this.ctx.arc(x, y, r, st, sp * Math.PI, dir);
            this.ctx.closePath();

            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }
            if (stroke) {
                this.ctx.strokeStyle = color_line;
                this.ctx.stroke();
            }
        },
        shape_rectangle: function (obj) {//矩形
            if (!obj) {
                return;
            }
            let x = obj.x || 0,
                w = obj.w || 0,
                h = obj.h || 0;
            let y = obj.y || 0,
                rot = obj.rotate || 0;
            let skewing_x = obj.skewing_x || 0,
                skewing_y = obj.skewing_y || 0;
            let line_w = obj.line_w || 1;
            let fill = obj.fill,
                stroke = obj.stroke;
            let color = obj.color,
                color_line = obj.color_line;

            x = x + skewing_x;
            y = y + skewing_y;
            rot = -rot * Math.PI / 180;
            this.ctx.beginPath();
            if (rot != 0) {
                this.ctx.translate(x, y);//修改原点到引脚中心
                this.ctx.rotate(rot);//旋转
                this.ctx.translate(-x, -y); // 平移
            }
            this.ctx.closePath();
            this.ctx.lineWidth = line_w;
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fillRect(x - w / 2, y - h / 2, w, h);
                this.ctx.fill();
            }
            if (stroke) {
                this.ctx.strokeStyle = color_line;
                this.ctx.strokeRect(x - w / 2, y - h / 2, w, h);
                this.ctx.stroke();
            }


        },
        shape_rectangle_c: function (obj) {//圆矩
            if (!obj) {
                return;
            }
            let x = obj.x || 0,
                w = obj.w || 0,
                h = obj.h || 0,
                r = obj.r || 0,
                y = obj.y || 0,
                rot = obj.rotate || 0;
            if (r == 0) {
                this.rectangle(obj);
                return;
            }
            let skewing_x = obj.skewing_x || 0,
                skewing_y = obj.skewing_y || 0;
            let line_w = obj.line_w || 1;
            let fill = obj.fill || true,
                stroke = obj.stroke || false;
            let color = obj.color,
                color_line = obj.color_line;
            x = x + skewing_x;
            y = y + skewing_y;
            rot = -rot * Math.PI / 180;
            var x1 = x - (w / 2 - r),
                y1 = y - h / 2,
                x2 = x1 + w - 2 * r,
                y2 = y1,
                j1_x = x + w / 2,
                j1_y = y1,

                x3 = x2 + r,
                y3 = y2 + r,
                x4 = x3,
                y4 = y3 + h - 2 * r,
                j2_x = x + w / 2,
                j2_y = y + h / 2,

                x5 = x2,
                y5 = y + h / 2,
                x6 = x1,
                y6 = y5,
                j3_x = x - w / 2,
                j3_y = y + h / 2,

                x7 = x6 - r,
                y7 = y6 - r,
                x8 = x7,
                y8 = y3,
                j4_x = x - w / 2,
                j4_y = y - h / 2;
            if (r < 0) {
                r = -r;
                x1 = x - (w / 2 - r);
                y1 = y - h / 2;
                x2 = x - (w / 2 - r) + w - 2 * r;
                y2 = y1;
                x3 = x2 + r;
                y3 = y2 + r;
                j1_x = x2;
                j1_y = y1 + r;

                x4 = x3;
                y4 = y3 + h - 2 * r;
                x5 = x2;
                y5 = y + h / 2;
                j2_x = x5;
                j2_y = y4;

                x6 = x1;
                y6 = y5;
                x7 = x6 - r;
                y7 = y6 - r;
                j3_x = x6;
                j3_y = y6 - r;

                x8 = x7;
                y8 = y3;
                j4_x = x1;
                j4_y = y8;
            }

            this.ctx.beginPath();
            this.ctx.lineCap = "round";
            this.ctx.lineJoin = "round";
            this.ctx.lineWidth = line_w;
            this.ctx.translate(x, y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x, -y); // 平移
            this.ctx.moveTo(x1, y1);
            this.ctx.lineTo(x2, y2);
            this.ctx.arcTo(j1_x, j1_y, x3, y3, r);
            this.ctx.lineTo(x4, y4);
            this.ctx.arcTo(j2_x, j2_y, x5, y5, r);
            this.ctx.lineTo(x6, y6);
            this.ctx.arcTo(j3_x, j3_y, x7, y7, r);
            this.ctx.lineTo(x8, y8);
            this.ctx.arcTo(j4_x, j4_y, x1, y1, r);
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }

            if (stroke) {
                this.ctx.strokeStyle = color_line;
                this.ctx.stroke();
            }

        },
        shape_octagon: function (obj) {//八角
            if (!obj) {
                return;
            }
            obj.num = 8;

            this.polygon(obj);
        },
        shape_long_circle: function (obj) {//长圆
            if (!obj) {
                return;
            }
            let x = obj.x || 0,
                r_x = obj.w / 1 || 0,
                r_y = obj.h / 1 || 0,
                y = obj.y || 0,
                rot = obj.rotate || 0;

            let skewing_x = obj.skewing_x || 0,
                skewing_y = obj.skewing_y || 0;
            let line_w = obj.line_w || 1;
            let fill = obj.fill,//||true,
                stroke = obj.stroke || false;
            let color = obj.color,
                color_line = obj.color_line;
            x = x / 1 + skewing_x / 1;
            y = y / 1 + skewing_y / 1;
            var width = r_x - r_y,
                height = r_y,
                arc_r = height / 2,
                start = x - width / 2,
                stop = y - height / 2;
            if (r_x < r_y) {
                width = r_y - r_x,
                    height = r_x,
                    arc_r = height / 2,
                    start = x - width / 2,
                    stop = y - height / 2;
                rot = rot + 90;
            }
            rot = -rot * Math.PI / 180;
            this.ctx.beginPath();
            this.ctx.translate(x, y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x, -y); // 平移s
            this.ctx.moveTo(start, stop);
            this.ctx.lineTo(start + width, stop);
            this.ctx.arcTo(start + width + arc_r, stop, start + width + arc_r, stop + height, arc_r);   // 创建一个弧
            this.ctx.arcTo(start + width + arc_r, stop + height, start, stop + height, arc_r);   // 创建一个弧
            this.ctx.lineTo(start, stop + height);
            this.ctx.arcTo(start - arc_r, stop + height, start - arc_r, stop, arc_r);
            this.ctx.arcTo(start - arc_r, stop, start, stop, arc_r);
            this.ctx.closePath();
            this.ctx.lineWidth = line_w || 1;
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }
            if (stroke) {
                this.ctx.strokeStyle = color_line
                this.ctx.stroke();
            }
        },
        shape_polygon: function (obj) {//正多边
            if (!obj) {
                return;
            }

            let num = obj.num / 1,
                org_rot = 0,  //默认补偿角度
                x = obj.x || 0,
                r = obj.r || 0,
                y = obj.y || 0,
                rot = obj.rotate || 0;//引脚旋转角度
            if (num < 3) {
                return;
            }
            //r=Math.sqrt((Math.pow(r/1,2)+Math.pow(r/2,2)));
            //计算默认补偿角度及半径
            if (num % 2 == 0) {
                if (num % 4 == 0) {
                    org_rot = 360 / num / 2;
                }
                r = r / Math.cos(Math.PI / 180 * org_rot);
            }
            if (num == 8) {
                rot += org_rot;
            }
            let skewing_x = obj.skewing_x || 0,
                skewing_y = obj.skewing_y || 0;
            let line_w = obj.line_w || 1;
            let fill = obj.fill || true,
                stroke = obj.stroke || false;
            let color = obj.color,
                color_line = obj.color_line;
            x = x + skewing_x;
            y = y + skewing_y;
            rot = -rot * Math.PI / 180;

            var startX = x + r * Math.cos(2 * Math.PI * 0 / num);//1
            var startY = y + r * Math.sin(2 * Math.PI * 0 / num);//0

            this.ctx.lineWidth = line_w;
            this.ctx.translate(x, y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x, -y); // 平移
            //开始路径
            this.ctx.beginPath();

            if (num % 2 == 1) {
                startX = x + r * Math.sin(2 * Math.PI * 0 / num);//1
                startY = y + r * Math.cos(2 * Math.PI * 0 / num);//0  
                this.ctx.moveTo(startX, startY);
                for (var i = 1; i <= num; i++) {
                    var newX = x + r * Math.sin(2 * Math.PI * i / num);
                    var newY = y + r * Math.cos(2 * Math.PI * i / num);
                    this.ctx.lineTo(newX, newY);
                }
            } else {
                this.ctx.moveTo(startX, startY);
                for (var i = 1; i <= num; i++) {
                    var newX = x + r * Math.cos(2 * Math.PI * i / num);
                    var newY = y + r * Math.sin(2 * Math.PI * i / num);
                    this.ctx.lineTo(newX, newY);
                }
            }
            this.ctx.closePath();
            this.ctx.lineWidth = 0;
            this.ctx.lineJoin = 'round';
            if (fill) {
                this.ctx.fillStyle = color
                this.ctx.fill();
            }

            if (stroke) {
                this.ctx.strokeStyle = color_line
                this.ctx.stroke();
            }

        },
        shape_path_p: function (obj) {//路径有中心点
            if (!obj || !obj.path || obj.path.length == 0) {
                return;
            }
            let color = obj.color,
                color_line = obj.color.color_line,
                stroke = obj.stroke || false,
                fill = obj.fill || true;
            let rot = obj.rotate || 0,
                x = obj.x,
                y = obj.y,
                r = 0,
                skewing_x = obj.skewing_x || 0,
                skewing_y = obj.skewing_y || 0;
            let o_x = 0,
                o_y = 0,
                name = '',
                st_x = '',
                st_y = '',
                sp_x = '',
                sp_y = '',
                head_x = [],
                head_y = [],
                img_num = 0,
                mode = '',
                lock = "",
                begin = 0,
                end = 0,
                line_w = 1;
            //if (rot == 90 || rot == 270) {
            //rot = -rot * Math.PI / 180;
            //} else {
            rot = -rot * Math.PI / 180;
            //}
            x = x + skewing_x;
            y = y + skewing_y;

            this.ctx.translate(x, y);
            this.ctx.rotate(rot);//旋转
            this.ctx.lineCap = "round";
            this.ctx.lineJoin = "round";
            this.ctx.beginPath();
            obj.path.forEach(path => {
                if (path) {
                    name = path.name.toUpperCase();
                    o_x = path.o_x;
                    o_y = path.o_y;
                    st_x = path.st_x;
                    st_y = path.st_y;
                    sp_x = path.sp_x;
                    sp_y = path.sp_y;
                    mode = path.arc_r;
                    line_w = path.width;
                    r = path.r;
                    if (line_w < 1) {
                        line_w = 1;
                    }
                    this.ctx.lineWidth = line_w;
                    if (name == "ARC") {//控制弧线方向
                        //console.log(st_x,st_y,sp_x,sp_y,o_x,o_y,r);
                        if (st_x == sp_x && st_y == sp_y) {
                            lock = "c";
                            begin = 10;
                            mode = true;
                        } else {
                            begin = this.radian_verdict(st_x - o_x, st_y - o_y);
                            end = this.radian_verdict(sp_x - o_x, sp_y - o_y);
                        }
                    }
                    //img_num新图形标志
                    if (img_num == 0) {
                        img_num += 1;
                        if (name == "LINE") {
                            this.ctx.moveTo(st_x, st_y);
                            this.ctx.lineTo(sp_x, sp_y);
                        } else if (name == "ARC") {

                            this.ctx.moveTo(st_x, st_y);
                            //ctx.arc(o_x,o_y,r,begin/3.14*Math.PI,end/3.14*Math.PI,mode);
                            this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            if (lock == "c") {
                                img_num = 0;
                                this.ctx.closePath();
                            }
                        }
                    } else {
                        //该判断现在的结束点是否在已知线段上
                        let lock_q = 0,
                            j = 1;
                        for (var i = 0; i <= head_x.length; i++) {//判断一个图形是不是结束了
                            if (sp_x == head_x[i] && sp_y == head_y[i]) {
                                lock_q += 1;
                                break;
                            }
                        }
                        if (lock_q > 0) {//尾坐标等于首坐标时判定图形闭合
                            if (name == "LINE") {
                                this.ctx.lineTo(sp_x, sp_y);
                            } else if (name == "ARC") {
                                this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            }
                            img_num = 0;
                            this.ctx.closePath();
                        } else {//绘制过程中
                            if (name == "LINE") {
                                this.ctx.lineTo(sp_x, sp_y);
                            } else if (name == "ARC") {
                                this.ctx.arc(o_x, o_y, r, begin, end, mode);
                                if (lock == "c") {
                                    img_num = 0;
                                    this.ctx.closePath();
                                }
                            }
                        }

                    }
                    head_x[head_x.length] = st_x;
                    head_y[head_y.length] = st_y;
                    head_x[head_x.length] = sp_x;
                    head_y[head_y.length] = sp_y;
                }
            });
            this.ctx.closePath();

            if (stroke) {
                this.ctx.strokeStyle = color_line;
                this.ctx.stroke();
            }
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }
            this.ctx.translate(-x, -y); // 平移

        },
        shape_path_l: function (obj) {//路径无中心点
            if (!obj || !obj.path || obj.path.length == 0) {
                return;
            }
            let color = obj.color,
                color_line = obj.color_line,
                stroke = obj.stroke || true,
                fill = obj.fill || false;
            let r = 0;
            let o_x = 0,
                o_y = 0,
                name = '',
                st_x = '',
                st_y = '',
                sp_x = '',
                sp_y = '',
                head_x = [],
                head_y = [],
                img_num = 0,
                mode = '',
                lock = "",
                begin = 0,
                end = 0;
            let buff_x = 0,
                buff_y = 0,
                line_w = obj.line_w;
            this.ctx.lineCap = "round";
            this.ctx.lineJoin = "round";
            this.ctx.beginPath();

            obj.path.forEach((path, a) => {

                if (path) {
                    name = path.name;
                    name = name.toUpperCase();
                    o_x = path.o_x;
                    o_y = path.o_y;
                    r = path.r;
                    st_x = path.st_x;
                    st_y = path.st_y;
                    sp_x = path.sp_x;
                    sp_y = path.sp_y;
                    mode = path.arc_r;
                    //.line_w || depl.line_width;
                    if (a == 0) {
                        buff_x = sp_x;
                        buff_y = sp_y;
                    }
                    if (line_w < 1) {
                        line_w = 1;
                    }
                    this.ctx.lineWidth = line_w;

                    if (name == "ARC") {//控制弧线方向
                        //console.log(st_x,st_y,sp_x,sp_y,o_x,o_y,r);
                        if (st_x == sp_x && st_y == sp_y) {
                            lock = "c";
                            begin = 10;
                            mode = true;
                        } else {
                            begin = this.radian_verdict(st_x - o_x, st_y - o_y);
                            end = this.radian_verdict(sp_x - o_x, sp_y - o_y);
                        }
                    }
                    //img_num新图形标志
                    if (img_num == 0) {
                        img_num += 1;
                        if (name == "LINE") {
                            this.ctx.moveTo(st_x, st_y);
                            this.ctx.lineTo(sp_x, sp_y);
                        } else if (name == "ARC") {
                            if (begin != 10) {
                                this.ctx.moveTo(st_x, st_y);
                            }

                            //ctx.arc(o_x,o_y,r,begin/3.14*Math.PI,end/3.14*Math.PI,mode);
                            this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            if (lock == "c") {
                                img_num = 0;
                                this.ctx.closePath();
                            }
                        }
                    } else {
                        //该判断现在的结束点是否在已知线段上
                        let lock_q = 0,
                            j = 1;
                        for (var i = 0; i <= head_x.length; i++) {//判断一个图形是不是结束了
                            //console.log((sp_y-head_y[i])/(head_y[j]-head_y[i]));
                            //console.log((sp_x-head_x[i])/(head_x[j]-head_x[i]));
                            if (sp_x == head_x[i] && sp_y == head_y[i]) {
                                lock_q += 1;
                                break;
                            }
                        }
                        if (lock_q > 0) {//尾坐标等于首坐标时判定图形闭合
                            if (name == "LINE") {
                                this.ctx.lineTo(sp_x, sp_y);
                            } else if (name == "ARC") {
                                this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            }
                            img_num = 0;
                            this.ctx.closePath();
                        } else {//绘制过程中
                            if (name == "LINE") {
                                this.ctx.lineTo(sp_x, sp_y);
                            } else if (name == "ARC") {
                                this.ctx.arc(o_x, o_y, r, begin, end, mode);
                                if (lock == "c") {
                                    img_num = 0;
                                    this.ctx.closePath();
                                }
                            }
                        }

                    }
                    head_x[head_x.length] = st_x;
                    head_y[head_y.length] = st_y;
                    head_x[head_x.length] = sp_x;
                    head_y[head_y.length] = sp_y;
                }
            });
            this.ctx.closePath();
            if (stroke) {
                this.ctx.strokeStyle = color_line;
                this.ctx.stroke();
            }
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }

        },
    };
    
    //标准图形方法
    var form_way={
        circle:function(obj){//圆形
            if(!obj){
                return;
            }
            let x=obj.x||0,
                r=obj.r||0;
            let y=obj.y||0;
            let skewing_x=obj.skewing_x||0,
                skewing_y=obj.skewing_y||0;
            let st=obj.st||0,
                sp=obj.sp||2;
            let dir=obj.arc_r||false,
                line_w=obj.line_w||1;
            let fill=obj.fill,//||true,
                stroke=obj.stroke;//;
            let color=obj.color,
                color_line=obj.color_line;
            
            x=x+skewing_x;
            y=y+skewing_y;
            
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.lineWidth=line_w;
            this.ctx.beginPath();	
            this.ctx.arc(x,y,r,st,sp*Math.PI,dir);
            this.ctx.closePath();

            if(fill){
                this.ctx.fillStyle=color;
                this.ctx.fill();
            }
            if(stroke){
                this.ctx.strokeStyle=color_line;
                this.ctx.stroke();
            }
            this.ctx.restore();
            this.setAlpha();
        },
        rectangle:function(obj){//矩形
            if(!obj){
                return;
            }
            let x=obj.x||0,
                w=obj.w||0,
                h=obj.h||0;
            let y=obj.y||0,
                rot=obj.rotate||0;
            let skewing_x=obj.skewing_x||0,
                skewing_y=obj.skewing_y||0;
            let line_w=obj.line_w||1;
            let fill=obj.fill,
                stroke=obj.stroke;
            let color=obj.color,
                color_line=obj.color_line;
            
            x=x+skewing_x;
            y=y+skewing_y;
            rot=-rot*Math.PI/180;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.beginPath();
            if(rot!=0) {
                this.ctx.translate(x,y);//修改原点到引脚中心
                this.ctx.rotate(rot);//旋转
                this.ctx.translate(-x,-y); // 平移
            }
            this.ctx.closePath();
            this.ctx.lineWidth = line_w||depl.line_width;
            if(fill){
               this.ctx.fillStyle=color||depl.layer_color;
               this.ctx.fillRect(x-w/2,y-h/2,w,h);
               this.ctx.fill();
            }
            if(stroke){
                this.ctx.strokeStyle=color_line||depl.p_line_color;
                this.ctx.strokeRect(x-w/2,y-h/2,w,h);
                this.ctx.stroke();
            }
            this.ctx.restore();  
            this.setAlpha();  
                
        },
        rectangle_c:function(obj){//圆矩
            if(!obj){
                return;
            }
            let x=obj.x||0,
                w=obj.w||0,
                h=obj.h||0,
                r=obj.r||0,
                y=obj.y||0,
                rot=obj.rotate||0;
            if(r==0){
                this.rectangle(obj);
                return;
            }     
            let skewing_x=obj.skewing_x||0,
                skewing_y=obj.skewing_y||0;
            let line_w=obj.line_w||1;
            let fill=obj.fill||true,
                stroke=obj.stroke||false;
            let color=obj.color,
                color_line=obj.color_line;
            x=x+skewing_x;
            y=y+skewing_y;
            rot=-rot*Math.PI/180;
            var x1=x -(w/2-r),
                y1=y-h/2,
                x2=x1+w-2*r,
                y2=y1,                              
                j1_x=x+w/2,   
                j1_y=y1,      
                                
                x3=x2+r,      
                y3=y2+r,      
                x4=x3,        
                y4=y3+h-2*r,  
                j2_x=x+w/2,   
                j2_y=y+h/2,   
                                
                x5=x2,        
                y5=y+h/2,     
                x6=x1,
                y6=y5 ,
                j3_x=x-w/2,
                j3_y=y+h/2,
                
                x7=x6-r,
                y7=y6-r,
                x8=x7,
                y8=y3,
                j4_x=x-w/2,
                j4_y=y-h/2;
            if(r<0){
                r=-r;  
                x1=x -(w/2-r);
                y1=y-h/2;
                x2=x -(w/2-r)+w-2*r;
                y2=y1;
                x3=x2+r;
                y3=y2+r;
                j1_x=x2;   
                j1_y=y1+r;
                
                x4=x3;
                y4=y3+h-2*r;
                x5=x2;
                y5=y+h/2;
                j2_x=x5;  
                j2_y=y4;
                
                x6=x1;
                y6=y5;
                x7=x6-r;
                y7=y6-r;
                j3_x=x6;   
                j3_y=y6-r;
                
                x8=x7;
                y8=y3;
                j4_x=x1;   
                j4_y=y8;
            }
            this.ctx.save();  
            this.setAlpha(obj.alpha); 
            this.ctx.beginPath();
            this.ctx.lineCap="round";
            this.ctx.lineJoin="round";
            this.ctx.lineWidth = line_w||depl.line_width;
            this.ctx.translate(x,y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x,-y); // 平移
            this.ctx.moveTo(x1,y1);
            this.ctx.lineTo(x2,y2);
            this.ctx.arcTo(j1_x, j1_y,x3, y3, r);
            this.ctx.lineTo(x4,y4);
            this.ctx.arcTo(j2_x, j2_y,x5,y5, r);
            this.ctx.lineTo(x6,y6);
            this.ctx.arcTo(j3_x, j3_y,x7, y7, r);
            this.ctx.lineTo(x8,y8);
            this.ctx.arcTo(j4_x, j4_y,x1,y1, r);
            if (fill) {
                this.ctx.fillStyle=color||_this.data.img_deploy.layer_color;
                this.ctx.fill();
            }
            
            if (stroke) {
                this.ctx.strokeStyle=color_line||_this.data.img_deploy.p_line_color;
                this.ctx.stroke();
            }
            this.ctx.restore();   
            this.setAlpha();
        },
        octagon:function(obj){//八角
            if(!obj){
                return;
            }
            obj.num=8;
            
            this.polygon(obj);
        },
        long_circle:function(obj){//长圆
            if(!obj){
                return;
            }
            let x=obj.x||0,
                r_x=obj.w/1||0,
                r_y=obj.h/1||0,
                y=obj.y||0,
                rot=obj.rotate||0;
                
            let skewing_x=obj.skewing_x||0,
                skewing_y=obj.skewing_y||0;
            let line_w=obj.line_w||1;
            let fill=obj.fill,//||true,
                stroke=obj.stroke||false;
            let color=obj.color,
                color_line=obj.color_line;
            x=x/1+skewing_x/1;
            y=y/1+skewing_y/1;
            var width=r_x-r_y,
                height=r_y,
                arc_r=height/2,
                start=x-width/2,
                stop=y-height/2;
            if(r_x<r_y){
                width=r_y-r_x,
                height=r_x,
                arc_r=height/2,
                start=x-width/2,
                stop=y-height/2;
                rot=rot+90;
            }
            rot=-rot*Math.PI/180;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.beginPath();
            this.ctx.translate(x,y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x,-y); // 平移s
            this.ctx.moveTo(start,stop);
            this.ctx.lineTo(start+width,stop); 
            this.ctx.arcTo(start+width+arc_r,stop,start+width+arc_r,stop+height,arc_r);   // 创建一个弧
            this.ctx.arcTo(start+width+arc_r,stop+height,start,stop+height,arc_r);   // 创建一个弧
            this.ctx.lineTo(start,stop+height);
            this.ctx.arcTo(start-arc_r,stop+height,start-arc_r,stop,arc_r);
            this.ctx.arcTo(start-arc_r,stop,start,stop,arc_r);
            this.ctx.closePath();
            this.ctx.lineWidth = line_w||1;
            if (fill) {
                this.ctx.fillStyle=color;
                this.ctx.fill();
            }
            if (stroke) {
                this.ctx.strokeStyle=color_line||_this.data.img_deploy.p_line_color;
                this.ctx.stroke();
            }
            this.ctx.restore();
            this.setAlpha();
        },
        polygon:function(obj){//正多边
            if(!obj){
                return;
            }
            
            let num=obj.num/1,
                org_rot=0,  //默认补偿角度
                x=obj.x||0,
                r=obj.r||0,
                y=obj.y||0,
                rot=obj.rotate||0;//引脚旋转角度
            if(num<3){
                return;
            }
            //r=Math.sqrt((Math.pow(r/1,2)+Math.pow(r/2,2)));
            //计算默认补偿角度及半径
            if(num%2==0){
                if(num%4==0){
                    org_rot=360/num/2;
                }
                r=r/Math.cos(Math.PI/180*org_rot);
            }
            if(num==8){
                rot+=org_rot;
            }
            let skewing_x=obj.skewing_x||0,
                skewing_y=obj.skewing_y||0;
            let line_w=obj.line_w||1;
            let fill=obj.fill||true,
                stroke=obj.stroke||false;
            let color=obj.color,
                color_line=obj.color_line;
            x=x+skewing_x;
            y=y+skewing_y;
            rot=-rot*Math.PI/180;

            var startX = x + r * Math.cos(2*Math.PI*0/num);//1
            var startY = y + r * Math.sin(2*Math.PI*0/num);//0
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.lineWidth=line_w;
            this.ctx.translate(x,y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x,-y); // 平移
            //开始路径
            this.ctx.beginPath();

            if(num%2==1){
                startX = x + r * Math.sin(2*Math.PI*0/num);//1
                startY = y + r * Math.cos(2*Math.PI*0/num);//0  
                this.ctx.moveTo(startX, startY);
                for(var i = 1; i <= num; i++) {
                    var newX = x + r * Math.sin(2*Math.PI*i/num);
                    var newY = y + r * Math.cos(2*Math.PI*i/num);
                    this.ctx.lineTo(newX, newY);
                }
            }else{
                this.ctx.moveTo(startX, startY);
                for(var i = 1; i <= num; i++) {
                    var newX = x + r * Math.cos(2*Math.PI*i/num);
                    var newY = y + r * Math.sin(2*Math.PI*i/num);
                    this.ctx.lineTo(newX, newY);
                }
            }
            this.ctx.closePath();
            this.ctx.lineWidth = 0;
            this.ctx.lineJoin = 'round';
            if (fill) {
                this.ctx.fillStyle=color||_this.data.img_deploy.layer_color;
                this.ctx.fill();
            }
            
            if (stroke) {
                this.ctx.strokeStyle=color_line||_this.data.img_deploy.p_line_color;
                this.ctx.stroke();
            }
            this.ctx.restore();
            this.setAlpha();
        },
        path_p:function(obj){//路径有中心点
            if (!obj||!obj.path||obj.path.length==0) {
                return;
            }
            let color = obj.color || depl.layer_color,
                color_line = obj.color.color_line || depl.line_color,
                stroke = obj.stroke || false,
                fill = obj.fill || true;
            let rot = obj.rotate || 0,
                x = obj.x,
                y = obj.y,
                r=0,
                skewing_x = obj.skewing_x||0,
                skewing_y = obj.skewing_y||0;
            let o_x = 0,
                o_y = 0,
                name = '',
                st_x = '',
                st_y = '',
                sp_x = '',
                sp_y = '',
                head_x = [],
                head_y = [],
                img_num = 0,
                mode = '',
                lock = "",
                begin = 0,
                end = 0,
                line_w = 1;
            //if (rot == 90 || rot == 270) {
                //rot = -rot * Math.PI / 180;
            //} else {
                rot = -rot * Math.PI / 180;
            //}
            x = x + skewing_x;
            y = y + skewing_y;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.translate(x,y);
            this.ctx.rotate(rot);//旋转
            this.ctx.lineCap = "round";
            this.ctx.lineJoin = "round";
            this.ctx.beginPath();
            obj.path.forEach(path => {
                if (path) {
                    name = path.name.toUpperCase();
                    o_x = path.o_x;
                    o_y = path.o_y;
                    st_x = path.st_x;
                    st_y = path.st_y;
                    sp_x = path.sp_x;
                    sp_y = path.sp_y;
                    mode = path.arc_r;
                    line_w = path.width ;
                    r=path.r;
                    if (line_w < 1) {
                        line_w = 1;
                    }
                    this.ctx.lineWidth = line_w;
                    if (name == "ARC") {//控制弧线方向
                        //console.log(st_x,st_y,sp_x,sp_y,o_x,o_y,r);
                        if (st_x == sp_x && st_y == sp_y) {
                            lock = "c";
                            begin = 10;
                            mode = true;
                        } else {
                            begin = this.radian_verdict(st_x - o_x, st_y - o_y);
                            end = this.radian_verdict(sp_x - o_x, sp_y - o_y);
                        }
                    }
                    //img_num新图形标志
                    if (img_num == 0) {
                        img_num += 1;
                        if (name == "LINE") {
                            this.ctx.moveTo(st_x, st_y);
                            this.ctx.lineTo(sp_x, sp_y);
                        } else if (name == "ARC") {
                           
                            this.ctx.moveTo(st_x, st_y);
                            //ctx.arc(o_x,o_y,r,begin/3.14*Math.PI,end/3.14*Math.PI,mode);
                            this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            if (lock == "c") {
                                img_num = 0;
                                this.ctx.closePath();
                            }
                        }
                    } else{
                        //该判断现在的结束点是否在已知线段上
                        let lock_q=0,
                            j=1;
                        for(var i=0;i<=head_x.length;i++){//判断一个图形是不是结束了
                            if(sp_x==head_x[i]&&sp_y==head_y[i]){
                                lock_q+=1;
                                break;
                            }
                        }
                        if(lock_q>0){//尾坐标等于首坐标时判定图形闭合
                            if(name=="LINE"){
                                this.ctx.lineTo(sp_x,sp_y);
                            }else if(name=="ARC"){
                                this.ctx.arc(o_x,o_y,r,begin,end,mode);
                            }
                            img_num=0;
                            this.ctx.closePath();
                        }else{//绘制过程中
                            if(name=="LINE"){
                                this.ctx.lineTo(sp_x,sp_y);
                            }else if(name=="ARC"){
                                this.ctx.arc(o_x,o_y,r,begin,end,mode);
                                if(lock=="c"){
                                    img_num=0;
                                    this.ctx.closePath();
                                }
                            }
                        }
                        
                    }
                    head_x[head_x.length] = st_x;
                    head_y[head_y.length] = st_y;
                    head_x[head_x.length] = sp_x;
                    head_y[head_y.length] = sp_y;
                }
            });
            this.ctx.closePath();
            
            if (stroke) {
                this.ctx.strokeStyle = color_line ;
                this.ctx.stroke();
            }
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }
            this.ctx.translate(-x, -y); // 平移
            this.ctx.restore();
            this.setAlpha();
        },
        path_l: function (obj) {//路径无中心点
            if (!obj || !obj.path || obj.path.length == 0) {
                return;
            }
            let color = obj.color || depl.layer_color,
                color_line = obj.color_line || depl.line_color,
                stroke = obj.stroke || true,
                fill = obj.fill || false;
            let r = 0;
            let o_x = 0,
                o_y = 0,
                name = '',
                st_x = '',
                st_y = '',
                sp_x = '',
                sp_y = '',
                head_x = [],
                head_y = [],
                img_num = 0,
                mode = '',
                lock = "",
                begin = 0,
                end = 0;
            let buff_x = 0,
                buff_y = 0,
                line_w = obj.line_w;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.lineCap = "round";
            this.ctx.lineJoin = "round";
            this.ctx.beginPath();

            obj.path.forEach((path,a) => {
                
                if (path) {
                    name = path.name;
                    name = name.toUpperCase();
                    o_x = path.o_x;
                    o_y = path.o_y;
                    r = path.r;
                    st_x = path.st_x;
                    st_y = path.st_y;
                    sp_x = path.sp_x;
                    sp_y = path.sp_y;
                    mode = path.arc_r;
                    //.line_w || depl.line_width;
                    if (a == 0) {
                        buff_x = sp_x;
                        buff_y = sp_y;
                    }
                    if (line_w < 1) {
                        line_w = 1;
                    }
                    this.ctx.lineWidth = line_w;
                   
                    if (name == "ARC") {//控制弧线方向
                        //console.log(st_x,st_y,sp_x,sp_y,o_x,o_y,r);
                        if (st_x == sp_x && st_y == sp_y) {
                            lock = "c";
                            begin = 10;
                            mode = true;
                        } else {
                            begin = this.radian_verdict(st_x - o_x, st_y - o_y);
                            end = this.radian_verdict(sp_x - o_x, sp_y - o_y);
                        }
                    }
                    //img_num新图形标志
                    if (img_num == 0) {
                        img_num += 1;
                        if (name == "LINE") {
                            this.ctx.moveTo(st_x, st_y);
                            this.ctx.lineTo(sp_x, sp_y);
                        } else if (name == "ARC") {
                            if(begin!=10){
                                this.ctx.moveTo(st_x, st_y);
                            }
                            
                            //ctx.arc(o_x,o_y,r,begin/3.14*Math.PI,end/3.14*Math.PI,mode);
                            this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            if (lock == "c") {
                                img_num = 0;
                                this.ctx.closePath();
                            }
                        }
                    } else {
                        //该判断现在的结束点是否在已知线段上
                        let lock_q = 0,
                            j = 1;
                        for (var i = 0; i <= head_x.length; i++) {//判断一个图形是不是结束了
                            //console.log((sp_y-head_y[i])/(head_y[j]-head_y[i]));
                            //console.log((sp_x-head_x[i])/(head_x[j]-head_x[i]));
                            if (sp_x == head_x[i] && sp_y == head_y[i]) {
                                lock_q += 1;
                                break;
                            }
                        }
                        if (lock_q > 0) {//尾坐标等于首坐标时判定图形闭合
                            if (name == "LINE") {
                                this.ctx.lineTo(sp_x, sp_y);
                            } else if (name == "ARC") {
                                this.ctx.arc(o_x, o_y, r, begin, end, mode);
                            }
                            img_num = 0;
                            this.ctx.closePath();
                        } else {//绘制过程中
                            if (name == "LINE") {
                                this.ctx.lineTo(sp_x, sp_y);
                            } else if (name == "ARC") {
                                this.ctx.arc(o_x, o_y, r, begin, end, mode);
                                if (lock == "c") {
                                    img_num = 0;
                                    this.ctx.closePath();
                                }
                            }
                        }

                    }
                    head_x[head_x.length] = st_x;
                    head_y[head_y.length] = st_y;
                    head_x[head_x.length] = sp_x;
                    head_y[head_y.length] = sp_y;
                }
            });
            this.ctx.closePath();
            if (stroke) {
                this.ctx.strokeStyle = color_line;
                this.ctx.stroke();
            }
            if (fill) {
                this.ctx.fillStyle = color;
                this.ctx.fill();
            }

            this.ctx.restore();
            this.setAlpha();
        },
        line: function (obj) {
            if(!obj){
                return;
            }
            let x_st=obj.st_x,
                y_st=obj.st_y,
                x_sp=obj.sp_x,
                y_sp=obj.sp_y;
            let line_w=obj.line_w||depl.line_width,
                color=obj.color||depl.line_color;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.beginPath();
            this.ctx.lineWidth=line_w||3;
            this.ctx.lineCap="round";
            this.ctx.lineJoin="round";
            this.ctx.strokeStyle = color;
            this.ctx.moveTo(x_st,y_st);
            this.ctx.lineTo(x_sp,y_sp);
            this.ctx.stroke();
            this.ctx.closePath();
            this.ctx.restore();
            this.setAlpha();
        },
        arc:function(obj){
            if(!obj){
                return;
            }
            let rot=obj.rotate,
                x=obj.x,
                y=obj.y,
                angle=obj.angle;
            let color =obj.color,
                dir=obj.direction||false,
                line_w=obj.line_w;
                
            if(Math.abs(angle)>360){//如果输入弧度值大于圆则取余
                angle=angle%360;
            }
            var angle_st=0,
                angle_sp=0;    
            
            
            //console.log(r,angle);
            if(angle>0&&r>0){//第四象限
                angle_sp=angle;
            }else if(angle<0&&r>0){//第三象限
                angle_st=90;
                angle_sp=-angle+angle_st;
            }else if(angle>0&&r<0){//第一象限
                angle_sp=angle;
            }else if(angle<0&&r<0){//第二象限
                angle_st=90;
                angle_sp=-angle+angle_st;
            }
            if(r<0){
                r=-r;
                dir=true;//逆时针
                angle_st=-angle_st;
                angle_sp=-angle_sp;
            }
            rot=-rot*Math.PI/180;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.translate(x,y);//修改原点到引脚中心
            this.ctx.rotate(rot);//旋转
            this.ctx.translate(-x,-y); // 平移
            this.ctx.lineWidth=line_w||_this.data.img_deploy.line_width;
            this.ctx.strokeStyle =color||_this.data.img_deploy.line_color;
            this.ctx.beginPath();	
            this.ctx.arc(x,y,r,angle_st*Math.PI/180,angle_sp*Math.PI/180,dir);
            this.ctx.stroke();
            this.ctx.restore();
            this.setAlpha();
        },
        arc_l:function(obj){
            let x=obj.x,
                y=obj.y,
                r=obj.r,
                st=obj.st,
                sp=obj.sp;
            let dir=obj.mode,
                line_w=obj.line_w,
                color=obj.color;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            this.ctx.lineWidth=line_w||depl.line_width;
            this.ctx.strokeStyle =color||depl.line_color;
            this.ctx.beginPath();	
            //this.ctx.arc(x,y,r,st/3.14*Math.PI,sp/3.14*Math.PI,dir);
            this.ctx.arc(x,y,r,st,sp,dir);
            this.ctx.stroke();
            this.ctx.restore();
            this.setAlpha();
        },
        text:function(obj){
            if(!obj||tidy.isEmpty(obj)){
                return;
            }
            let fontwidth=obj.fontWeight||"bold";
            let x=obj.x,
                y=obj.y,
                rot=obj.rot,
                skewing_x=obj.skewing_x/1||0,
                skewing_y=obj.skewing_y/1||0,
                textSize=obj.text_size,
                color=obj.color||depl.text_color,
                typeface=obj.typeface||depl.typeface;
            let txt=obj.content;
            x=x/1+skewing_x/1;
            y=y/1+skewing_y/1;
            rot=-rot*Math.PI/180;
            this.ctx.save();
            this.setAlpha(obj.alpha);
            if(rot!=0){
                this.ctx.translate(x,y);//修改原点到引脚中心
                this.ctx.rotate(rot);//旋转
                this.ctx.translate(-x,-y); // 平移
            }
            if(obj.back){
                let number=txt.length,
                    w=number*text_size,
                    h=text_size;
                let max_x=x+w/2,
                    max_y=y+h/2,
                    min_x=x-w/2,
                    min_y=y-h/2;
                this.ctx.save();
                this.ctx.fillStyle="green";
                this.ctx.beginPath();
                this.ctx.lineWidth = "3";
                this.ctx.strokeStyle = "blue";
                this.ctx.fillStyle = "orange";
                this.ctx.moveTo(min_x, max_y);
                this.ctx.lineTo(max_x, max_y);
                this.ctx.lineTo(max_x, min_y);
                this.ctx.lineTo(min_x, min_y);
                this.ctx.closePath();
                this.ctx.fill();
                this.ctx.restore();
            }
            this.ctx.fillStyle=color;//字体颜色
            this.ctx.textBaseline="middle";
            this.ctx.strokeStyle =color;//设置边框颜色
            //" style variant weight 12px arial"
            this.ctx.font = "normal normal "+fontwidth+" "+textSize+"px "+typeface;
            this.ctx.textAlign = "center";  
            if(obj.textAlign){
                this.ctx.textAlign = obj.textAlign;
            }
            
            this.ctx.fillText(txt, x, y);
            var measure = this.ctx.measureText(txt,x,y);//文本对象
            //矩形描边
            if(obj.strokeRect){
                this.rectangle({
                    x:x,
                    y:y,
                    w:measure.width,
                    h:textSize,
                    color_line:obj.strokeRect,
                    stroke:true,
                    fill:false,
                    line_w:textSize/20,
                })
            }
            this.ctx.restore();
            this.setAlpha();
            return measure;
        },
        rectangleBox:function(obj){
            this.fix_point(obj.box1)
            if(obj.lock){
                let x1  = obj.gap.x1 , 
                    y1  = obj.gap.y1 ,
                    x2  = obj.gap.x2 ,
                    y2  = obj.gap.y2 ,
                    x3  = obj.gap.x3,
                    y3  = obj.gap.y3,
                    x4  = obj.gap.x4,
                    y4  = obj.gap.y4,
                    o_x = obj.gap.o_x,
                    o_y = obj.gap.o_y;
                this.ctx.save()
                this.ctx.lineWidth=2; 
                this.ctx.strokeStyle="green";
                this.ctx.beginPath();
                this.ctx.moveTo(x1,y1);
                this.ctx.lineTo(x3,y3);
                this.text(obj.gap.txt); //距离
                this.text(obj.gap.txtw); //距离
                this.text(obj.gap.txth); //距离
                this.ctx.moveTo(x4,y4);
                this.ctx.lineTo(x2,y2);
                this.ctx.setLineDash([6]);//虚线
                this.ctx.stroke();
                this.ctx.restore();
                this.fix_point(obj.box2)
            }
            
        },
        fix_point:function(obj){
            let row1 = obj.row1,
                row2 = obj.row2,
                x= obj.x,
                y=obj.y,
                k=obj.k||obj.w||8;;
            //这是矩形框
            this.ctx.save();
            this.ctx.strokeStyle="green";
            this.ctx.lineWidth=1;  
            this.ctx.beginPath();  
            this.ctx.moveTo(x-k/8,y-k/8);
            this.ctx.lineTo(x+k/8,y+k/8);
            this.ctx.moveTo(x+k/8,y-k/8);
            this.ctx.lineTo(x-k/8,y+k/8);
            this.ctx.rect(x-k/8,y-k/8,k/4,k/4);
            this.ctx.stroke(); 
            this.ctx.restore();
            if(obj.lock){
                this.text(row1);
                this.text(row2);
            }
        },
        radian_verdict:function(x,y){//获取弧度
            var angle=0;
            if(x>0&&y>=0){
                angle=Math.atan(y/x);
            }else if(x<=0&&y>0){
                x=Math.abs(x);
                angle=Math.atan(x/y)+0.5*Math.PI;
            }else if(x<0&&y<=0){
                x=Math.abs(x);
                y=Math.abs(y);
                angle=Math.atan(y/x)+Math.PI;
            }else if(x>=0&&y<0){
                y=Math.abs(y);
                angle=Math.atan(x/y)+1.5*Math.PI;
            }
            return angle;
        },
        arrowhead:function(obj){//绘制箭头
            //console.log(obj);
            
            this.ctx.save();
            this.ctx.strokeStyle = '#4915daf2';
            this.ctx.lineWidth = 2;
            this.ctx.beginPath();
            this.ctx.moveTo(obj.st_x, obj.st_y);// 起始点
            this.ctx.quadraticCurveTo(obj.con_x, obj.con_y, obj.sp_x, obj.sp_y);
            this.ctx.stroke();
            this.ctx.restore();
        },
        
    };
    function draw(canvas){

        this.actual_canvas=canvas; //实际画布
        this.canvasRoatate = 45;
        //draw.prototype=img_create;
        this.actual_ctx = this.createCtx();//最终图形画笔
        this.ctx = this.createVirCtx(this.actual_canvas.width,this.actual_canvas.height);//虚拟画笔;
        //Object.setPrototypeOf(this.ctx.prototype,tool);
        
    };
    Object.assign(draw.prototype,tool,form_way,Shape_way);
    return draw;
})();

export default ImgDraw;

